#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int tamanho(FILE *fl)
{
	int i,tam[4];
	for(i=0;i<4;i++) tam[i]=getc(fl);
	return tam[3]+tam[2]*pow(2,7)+tam[1]*pow(2,14)+tam[0]*pow(2,21);
}

char *info(FILE *fl, int *tam)
{
	char *tag=malloc(5*sizeof(char));	
	char *flag=malloc(2*sizeof(char)),j;
	int i;
	for(i=0;i<4;i++) tag[i]=getc(fl);
	tag[4]=10;
	*tam=tamanho(fl);
	for(i=0;i<2;i++) flag[i]=getc(fl);
	j=getc(fl);
	free(flag);
	return tag;
}

int main(int argc, char *argv[])
{
	int i=0,tam=0,resto=0,verdade=0,sync,bit_rate,sample,frame_len;
	int version,cntd=0,mul=1,layer,crc,padding,channel,emphasis,conta=0;
    unsigned char *head=malloc(4*sizeof(char));
	unsigned char var,*conteudo;
	char *codigo=malloc(3*sizeof(char));
	char *str=malloc(5*sizeof(char));
	FILE *fp,*ff;
	fp=fopen("radioactive - imagine dragon.mp3","r");
	for(i=0;i<3;i++) codigo[i]=getc(fp);
	printf("Indentificador de Arquivo: %s\n",codigo);
	free(codigo);

	for(i=0;i<2;i++)
	{
		var=getc(fp);
		if(i==0) printf("Major Version: %d\n",var);
		if(i==1) printf("Revisison Number: %d\n",var);
	}

	var=getc(fp);
	if(var&128==128) printf("Unsynchronisation  [YES]\n");
	else printf("Unsynchronisation  [NO]\n");
	if(var&64==64) printf("Extended Header    [YES]\n");
	else printf("Extended Header    [NO]\n");
	if(var&32==32) printf("Experimental Stage [YES]\n");
	else printf("Experimental Stage [NO]\n");

	int w=tamanho(fp);
	printf("O tamanho do header é de: %d Bytes\n",w);

	char *tags;
	while(resto<w)
	{
		tags=info(fp, &tam);	
		//printf("%s",tags);
		ff=fopen("frames.txt","r");
		while(!feof(ff) && verdade==0)
		{
			for(i=0;i<5;i++) str[i]=getc(ff);
			if(strcmp(tags,str)==0) verdade=1;
			else verdade=0;
		}
		fclose(ff);
		if(verdade==1)
		{
			conteudo=malloc((tam-1)*sizeof(char));
			for(i=0;i<tam-1;i++) conteudo[i]=getc(fp);
			printf("%s\n",conteudo);
			free(tags);
			resto=resto+10+tam;
			verdade=0;
		}
		else resto=w;
	}	
	free(conteudo);		
	free(str);
	fseek(fp,w+10,SEEK_SET);
	while(!feof(fp))
	{
		for(i=0;i<4;i++) head[i]=getc(fp);
		sync=(head[0]*pow(2,3))+((head[1]&224)/pow(2,5));
		//for(i=0;i<4;i++) printf("%x ",head[i]);
		//puts("");
		bit_rate=(head[2]&240)/pow(2,4);
		sample=(head[2]&12)/pow(2,2);
		//printf("%d %d %d\n",sync,bit_rate,sample);
		if(sync==2047  && bit_rate!=15  && sample!=3)
		{
			version=(head[1]&24)/pow(2,3);
			layer=(head[1]&6)/2;
			crc=head[1]&1;
			padding=(head[2]&2)/2;
			channel=(head[3]&192)/pow(2,6);
			emphasis=head[3]&3;
			if(sample==0) sample=44100;
			else if(sample==1) sample=48000;
			else sample=32000;
			if (bit_rate==0) bit_rate=sample;	
			else if ((bit_rate>0)&&(bit_rate<=5))
			bit_rate=(32+(bit_rate-1)*8)*1000;
			else if ((bit_rate>5)&&(bit_rate<10))
			bit_rate=(80+(bit_rate-6)*16)*1000;
			else if ((bit_rate>=10)&&(bit_rate<=13))
			bit_rate=(160+(bit_rate-10)*32)*1000;
			else bit_rate=320000;
			frame_len=(144*bit_rate/sample)+padding;
			cntd++;
			//printf("%d %d %d %d\n",frame_len,bit_rate,sample,cntd);
			//if(frame_len==0) resto=0;
			if(cntd==1000*mul)
			{
				mul++;
				getchar();
			}
			fseek(fp,frame_len-4,SEEK_CUR);
			conta=conta+frame_len;
		}
		else
		{
			//puts("ok");
			//getchar();
			conta++;
			fseek(fp,w+10+conta,SEEK_SET);
		}
	}
	fclose(fp);
	return 0;
}
